package metar;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

import model.WeatherModel;
import model.WindModel;

/**
 * Abholen der MetarInfo des Flughafens und Konvertierung ins WeatherModel
 * @author Michel Metzger, Java-Kurs 2013
 * @version 1.0.0
 * 
 */
public class MetarReader {

	/**
	 * Flughafencode
	 */
	private String airport;

	/**
	 * Standard-Konstruktor
	 */
	public MetarReader() {
	}

	/**
	 * Konstruktor mit Angabe des Flughafens
	 * 
	 * @param airport
	 */
	public MetarReader(String airport) {
		super();
		this.airport = airport;
	}

	/**
	 * Flughafen für Abfrage setzen
	 * 
	 * @param airport
	 */
	public void setAirport(String airport) {
		this.airport = airport;
	}

	/**
	 * Metar-Info über http abholen
	 * 
	 * @return
	 * @throws MetarLogException
	 * @throws MetarParseException 
	 */
	public WeatherModel getMetarInfo() throws MetarLogException, MetarParseException {

		MetarInfo mi = readMetarInfo();
		if (mi != null) {
			WeatherModel wm = new WeatherModel();
			wm.setCityID(mi.getAirportCode());
			wm.setInfo(this.airport);
			if (mi.getTemperature() != null) {
				wm.setTemperature(mi.getTemperature().getTemp());
			}
			if (mi.getWind() != null) {
				wm.setWindDirectionInfo(mi.getWind().getOrigParam());
				WindModel wind = new WindModel();
				wind.populate(mi.getWind().getOrigParam());
//				wind.setSpeedKnot(mi.getWind().getSpeed());
//				wind.setDirection(mi.getWind().getDirection());
				wm.setWind(wind);
			}
			if (mi.getObservationDate() != null) {
				wm.setObservationTime(mi.getObservationDate().getOrigParam());
				wm.setTimeStamp(mi.getObservationDate().getDate().getTime());
			}
			wm.setDate(mi.getRetrievalDate());
			if (mi.getVisibility() != null) {
				wm.setVisibility(mi.getVisibility().getVisibility());
			}
			if (mi.getPressure() != null) {
				wm.setAirPressure(mi.getPressure().getPressure());
			}
			if (mi.getClouds() != null && mi.getClouds().size() > 0) {
				wm.setCloudiness(mi.getClouds().get(0).getOrigParam());
			}
			return wm;
		}

		return null;
	}

	/**
	 * Metar-Info für den angegebenen Flughafen abholen
	 * 
	 * @param airport
	 * @return
	 * @throws MetarParseException 
	 * @throws MetarLogException 
	 */
	public WeatherModel getMetarInfo(String airport) throws MetarLogException, MetarParseException {
		this.airport = airport;
		return getMetarInfo();
	}

	/**
	 * interne Methode zum Abholen der Daten
	 * 
	 * @return
	 * @throws MetarLogException
	 * @throws MetarParseException
	 */
	private MetarInfo readMetarInfo() throws MetarLogException, MetarParseException {

		final String httpURL = "http://weather.noaa.gov/pub/data/observations/metar/stations/";

		BufferedReader br = null;

		try {
			URL url = new URL(httpURL + airport.toUpperCase() + ".TXT");

			if (MetarInfo.isDebugMode()) {
				System.out.println("URL=" + url);
			}

			br = new BufferedReader(new InputStreamReader(url.openConnection().getInputStream()));

			String info = "";
			String line;
			while ((line = br.readLine()) != null) {
				if (info.length() > 0) {
					info += "\n";
				}
				info += line;
			}

			if (MetarInfo.isDebugMode()) {
				System.out.println("info=" + info);
			}

			LogFile.writeToLogFile(info);

			MetarInfo mi = new MetarInfo();
			mi.parse(info);
			br.close();

			return mi;
		} catch (IOException e) {
			System.out.println("Error reading data for: " + airport);
//			if (MetarInfo.isDebugMode()) {
//				e.printStackTrace();
//			}
//			throw new MetarParseException("IO-Error, maybe airport-code is unknown!");
		} finally {
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					// wenn das Schließen schief geht, wird das ignoriert
				}
			}
		}
		
		return null;
	}
}
